import asyncio
import datetime
from contextlib import asynccontextmanager

import pymongo
import uvicorn
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import RequestValidationError
from starlette.responses import JSONResponse

from handle_log import HandleLog
from xmlapi import main

# 设置日志格式
log = HandleLog()

# 假设你已经有一个MongoDB的连接
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["iBox"]
collection = db["channels"]


# 定义定时任务函数
def job_function():
    log.info(f"定时任务执行时间: {datetime.datetime.now()}")
    # ========Python 3.7及以上版本才支持asyncio.run()=====
    asyncio.run(main())
    # ========Python 3.6及以下版本使用以下代码============
    # loop = asyncio.new_event_loop()
    # asyncio.set_event_loop(loop)
    # try:
    #     loop.run_until_complete(asyncio.gather(main()))
    # finally:
    #     loop.close()
    #     pass


# 创建调度器实例
scheduler = AsyncIOScheduler()

# 添加定时任务，每天01:00执行一次job_function
scheduler.add_job(
    id="job1", func=job_function, trigger="cron", hour=1, minute=0, second=0
)


@asynccontextmanager
async def lifespan(app: FastAPI):
    log.warning("启动前执行")
    scheduler.start()
    yield
    log.warning("关闭后前执行")
    scheduler.shutdown()


# 构建FastAPI应用
app = FastAPI(lifespan=lifespan)


@app.exception_handler(RequestValidationError)
async def request_validation_exception_handler(
    request: Request, exc: RequestValidationError
):
    log.info(f"参数不对{request.method} {request.url}")
    return JSONResponse({"code": "400", "msg": exc.errors()})


@app.get("/")
async def hello():
    return JSONResponse({"code": "200", "msg": "请求成功!", "data": "Hello world!!"})


@app.get("/api")
async def get_channel(ch: str = "", date: str = ""):
    if ch and date:
        log.info(f"频道为: {ch}, 日期为: {date}")
        # 在MongoDB中查询对应的数据
        query = {"channel_name": ch.lower(), "date": date}
        # log.info(f"query:{query}")
        # 使用projection参数来排除不需要的字段
        projection = {"_id": 0}  # 排除_id字段
        result = collection.find_one(query, projection)
        # log.info(f"result:{result}")
        if result:
            return result
            # return JSONResponse({
            #     'code': '200',
            #     'msg': '请求成功!',
            #     'data': result
            # })
        else:
            return JSONResponse({"code": "404", "msg": "请求成功!", "data": "未找到对应的数据"})
    else:
        return JSONResponse({"code": "404", "msg": "请求成功!", "data": "参数获取不完整"})


if __name__ == "__main__":
    uvicorn.run(app="main:app", host="127.0.0.1", port=9999, reload=True)